unit DragSignal1;

interface

uses Windows,  Classes, Controls, Graphics, StdCtrls, Messages, ExtCtrls, Menus, MedaxObjects ;

type
	TSignal = class
	private
		{ Private declarations }
       FPin : TMedaPin ;					{ originating Pin }
       FHere, FOldHere : TPoint ;
       FOnMouseDown : TMouseEvent ;
       FOnMouseMove : TMouseMoveEvent ;
       FOnMouseUp : TMouseEvent ;
       FPaintBox : TPaintBox ;
       FZoom : integer ;
       FPopup : TPopupMenu ;
       FDirection : set of TMedaDir ;
	protected
   	{ Protected declarations }
	public
		{ Public declarations }
		constructor Create( PaintBox : TPaintBox; Pin : TMedaPin ) ;
       procedure MouseMove( Sender: TObject; Shift: TShiftState; X, Y: Integer ) ;
       procedure MouseUp( Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer ) ;
       procedure MouseDown( Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer ) ;
//		destructor Destroy ; virtual ;
   published
		{ Published declarations }
  end;


implementation

constructor TSignal.Create( PaintBox : TPaintBox; Pin : TMedaPin ) ;
begin
	inherited Create ;
   FPaintBox := PaintBox ;
   FPin := Pin ;
   FDirection := [ FPin.Direction ] ;
   FPopup := FPaintBox.PopupMenu ;
   FPaintBox.PopupMenu := nil ;
   FZoom := FPaintBox.Tag ;
   FOnMouseDown := FPaintBox.OnMouseDown ;
	FOnMouseMove := FPaintBox.OnMouseMove ;
   FOnMouseUp := FPaintBox.OnMouseUp ;
	FPaintBox.OnMouseDown := MouseDown ;
	FPaintBox.OnMouseMove := MouseMove ;
	FPaintBox.OnMouseUp := MouseUp ;
	FOldHere.X := -1 ;
   FOldHere.Y := -1 ;
end ;

procedure TSignal.MouseMove( Sender: TObject; Shift: TShiftState; X, Y: Integer );
var
	hDC, nWidth : integer ;
begin
	with FPaintBox.Canvas do begin
   	hDC := Handle ;
       nWidth := Pen.Width ;
       FHere := Point( ( X + FZoom div 2 ) div FZoom, ( Y + FZoom div 2 ) div FZoom ) ;
       if ( FHere.X <> FOldHere.X ) or ( FHere.Y <> FOldHere.Y ) then begin
       	if FOldHere.X > -1 then
		       	PatBlt( hDC, FPin.X * FZoom, FPin.Y * FZoom, FOldHere.X * FZoom - FPin.X * FZoom, nWidth, DSTINVERT ) ;
       	PatBlt( hDC, FPin.X * FZoom, FPin.Y * FZoom, FHere.X * FZoom - FPin.X * FZoom, nWidth, DSTINVERT ) ;
           FOldHere := FHere ;
       end ;
   end ;
end ;

procedure TSignal.MouseDown( Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer ) ;
var
	hDC, nWidth : integer ;
begin
	{ only line corners here }
	if Button <> mbRight then
   	Exit ;

   { turn 90 or 270 degrees }
   if drEast in FDirection then
      FDirection := [ drNorth, drSouth ]
   else if drWest in FDirection then
      FDirection := [ drNorth, drSouth ]
   else if drNorth in FDirection then
      FDirection := [ drWest, drEast ]
   else if drSouth in FDirection then
      FDirection := [ drWest, drEast ] ;

	with FPaintBox.Canvas do begin
      	PatBlt( hDC, FPin.X * FZoom, FPin.Y * FZoom, FHere.X * FZoom - FPin.X * FZoom, nWidth, DSTINVERT ) ;
       FOldHere := Point( ( X + FZoom div 2 ) div FZoom, ( Y + FZoom div 2 ) div FZoom ) ;
		MoveTo( FPin.X * FZoom, FPin.Y * FZoom ) ;
		LineTo( FHere.X * FZoom, FHere.Y * FZoom ) ;
   end ;
end ;

procedure TSignal.MouseUp( Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer ) ;
begin
	if Button <> mbLeft then
   	Exit ;
	with FPaintBox.Canvas do begin
       FHere := Point( ( X + FZoom div 2 ) div FZoom, ( Y + FZoom div 2 ) div FZoom ) ;
      	FPaintBox.Refresh ;
		MoveTo( FPin.X * FZoom, FPin.Y * FZoom ) ;
		LineTo( FHere.X * FZoom, FHere.Y * FZoom ) ;
   end ;
	FPaintBox.OnMouseDown := FOnMouseDown ;
	FPaintBox.OnMouseMove := FOnMouseMove ;
	FPaintBox.OnMouseUp := FOnMouseUp ;
   FPaintBox.PopupMenu := FPopup ;
   Free ;
end ;

end.
 